package tum0r.webengine.extension

import com.alibaba.fastjson.JSONArray
import java.sql.ResultSet

/**
 * 说明: 数据库查询结果扩展
 *
 * 创建者: tum0r
 *
 * 时间: 2021/8/19 20:46
 */

/**
 * Kotlin调用，将数据库查询结果的一行转为强类型对象
 *
 * @return 强类型对象集合
 */
inline fun <reified T> ResultSet.selectObjects(): ArrayList<T> = this.selectObjects(T::class.java)

/**
 * Java调用，将数据库查询结果的一行转为强类型对象
 *
 * @return 强类型对象集合
 */
fun <T> ResultSet.selectObjects(targetClass: Class<T>): ArrayList<T> {
    val result = ArrayList<T>()
    if (!this.isClosed && !targetClass.isPrimitiveType()) {
        val fields = targetClass.getAllFields(true)
        val metaData = this.metaData
        val columnCount = metaData.columnCount
        val columnName = Array(columnCount + 1) { "" }
        for (i in 1..columnCount)
            columnName[i] = metaData.getColumnName(i)
        while (this.next()) {
            val item = targetClass.getConstructor().newInstance()
            var index: Int
            for (field in fields)
                if (columnName.lastIndexOf(field.name).also { index = it } >= 1)
                    field.setObjectValue(item, this.getString(index))
            result.add(item as T)
        }
    }
    return result
}

/**
 * Kotlin调用，将数据库查询结果的第一列转为要求的值类型
 *
 * @return 值类型集合
 */
inline fun <reified T> ResultSet.selectValues(): ArrayList<T> = this.selectValues(T::class.java)

/**
 * Kotlin调用，将数据库查询结果的第一列转为要求的值类型
 *
 * @return 值类型集合
 */
fun <T> ResultSet.selectValues(targetClass: Class<T>): ArrayList<T> {
    val result = ArrayList<T>()
    if (!this.isClosed && targetClass.isPrimitiveType()) if (this.metaData.columnCount > 0) while (this.next()) result.add(this.getObject(1, targetClass))
    return result
}

/**
 * 查询数据库，第一个Array为查询结果的列名，允许有名称重复的列
 */
fun ResultSet.selectListArray(): ArrayList<Array<Any?>> {
    val result = ArrayList<Array<Any?>>()
    if (this.isClosed) return result
    val metaData = this.metaData
    val columnCount = metaData.columnCount
    if (columnCount == 0) return result
    val columnName = Array(columnCount) { "" }
    for (i in 1..columnCount)
        columnName[i - 1] = metaData.getColumnName(i)
    result.add(columnName as Array<Any?>)
    while (this.next()) {
        val item = Array<Any?>(columnCount) { null }
        for (i in 1..columnCount)
            item[i - 1] = this.getObject(i)
        result.add(item)
    }
    return result
}

/**
 * 查询数据库，不允许有名称重复的列
 */
fun ResultSet.selectListMap(): ArrayList<LinkedHashMap<String, Any?>> {
    val result = ArrayList<LinkedHashMap<String, Any?>>()
    val temp = this.selectListArray()
    if (temp.size == 0) return result
    val columnName = temp.removeFirst() as Array<String>
    for (list in temp) {
        val resultItem = LinkedHashMap<String, Any?>()
        for (i in list.indices)
            resultItem[columnName[i]] = list[i]
        result.add(resultItem)
    }
    return result
}

/**
 * 查询数据库，不允许有名称重复的列
 */
fun ResultSet.selectJSON(): JSONArray = this.selectListMap().toJSONArray()